import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useAuthStore = defineStore('auth', () => {
  // 状态
  const user = ref(null)
  const token = ref(null)
  const isLoading = ref(false)

  // 计算属性
  const isAuthenticated = computed(() => !!token.value)
  const userInfo = computed(() => user.value)
  const userRole = computed(() => user.value?.role || '')

  // 初始化 - 从本地存储恢复状态
  const initAuth = () => {
    const savedToken = localStorage.getItem('auth_token')
    const savedUser = localStorage.getItem('auth_user')

    if (savedToken && savedUser) {
      token.value = savedToken
      try {
        user.value = JSON.parse(savedUser)
      } catch (error) {
        console.error('解析用户信息失败:', error)
        clearAuth()
      }
    }
  }

  // 登录
  const login = async credentials => {
    try {
      isLoading.value = true

      // 模拟 API 调用
      const response = await mockLoginAPI(credentials)

      // 保存用户信息和 token
      user.value = response.user
      token.value = response.token

      // 根据是否记住我来决定存储方式
      if (credentials.rememberMe) {
        localStorage.setItem('auth_token', response.token)
        localStorage.setItem('auth_user', JSON.stringify(response.user))
      } else {
        sessionStorage.setItem('auth_token', response.token)
        sessionStorage.setItem('auth_user', JSON.stringify(response.user))
      }

      return response
    } catch (error) {
      throw new Error(error.message || '登录失败')
    } finally {
      isLoading.value = false
    }
  }

  // 登出
  const logout = async () => {
    try {
      isLoading.value = true

      // 如果需要调用后端登出接口
      // await api.logout()

      clearAuth()
    } catch (error) {
      console.error('登出失败:', error)
      // 即使登出接口失败，也要清除本地状态
      clearAuth()
    } finally {
      isLoading.value = false
    }
  }

  // 清除认证信息
  const clearAuth = () => {
    user.value = null
    token.value = null
    localStorage.removeItem('auth_token')
    localStorage.removeItem('auth_user')
    sessionStorage.removeItem('auth_token')
    sessionStorage.removeItem('auth_user')
  }

  // 检查 token 是否有效
  const checkAuth = async () => {
    if (!token.value) {
      return false
    }

    try {
      // 模拟验证 token 的 API 调用
      const isValid = await mockVerifyToken(token.value)

      if (!isValid) {
        clearAuth()
        return false
      }

      return true
    } catch (error) {
      console.error('验证 token 失败:', error)
      clearAuth()
      return false
    }
  }

  // 更新用户信息
  const updateUser = newUserInfo => {
    user.value = { ...user.value, ...newUserInfo }

    // 更新存储的用户信息
    const storage = localStorage.getItem('auth_token') ? localStorage : sessionStorage
    storage.setItem('auth_user', JSON.stringify(user.value))
  }

  // 获取认证头
  const getAuthHeader = () => {
    return token.value ? { Authorization: `Bearer ${token.value}` } : {}
  }

  return {
    // 状态
    user,
    token,
    isLoading,

    // 计算属性
    isAuthenticated,
    userInfo,
    userRole,

    // 方法
    initAuth,
    login,
    logout,
    clearAuth,
    checkAuth,
    updateUser,
    getAuthHeader
  }
})

// 模拟登录 API
const mockLoginAPI = async credentials => {
  // 模拟网络延迟
  await new Promise(resolve => setTimeout(resolve, 1000))

  // 模拟登录验证
  const validCredentials = [
    { username: 'admin', password: 'qwer1234' },
    { username: 'manager', password: 'password' },
    { username: 'user', password: 'qwer1234' }
  ]

  const isValid = validCredentials.some(cred => cred.username === credentials.username && cred.password === credentials.password)

  if (!isValid) {
    throw new Error('用户名或密码错误')
  }

  // 模拟返回的用户信息和 token
  return {
    user: {
      id: 1,
      username: credentials.username,
      email: `${credentials.username}@example.com`,
      role: credentials.username === 'admin' ? 'admin' : 'user',
      avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${credentials.username}`,
      loginTime: new Date().toISOString()
    },
    token: `mock_token_${credentials.username}_${Date.now()}`
  }
}

// 模拟验证 token 的 API
const mockVerifyToken = async token => {
  // 模拟网络延迟
  await new Promise(resolve => setTimeout(resolve, 500))

  // 简单的 token 格式验证
  return token && token.startsWith('mock_token_')
}
